package com.example.aircraft.gamemode;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;

import android.os.Build;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;


import androidx.annotation.NonNull;

import com.example.aircraft.EnemyObject;
import com.example.aircraft.HeroController;
import com.example.aircraft.ImageManager;
import com.example.aircraft.MyApplication;
import com.example.aircraft.R;
import com.example.aircraft.panel.DualSignPanel;
import com.example.aircraft.aircraft.AbstractAircraft;
import com.example.aircraft.aircraft.Enemy;
import com.example.aircraft.aircraft.EnemyFactory;
import com.example.aircraft.aircraft.HeroAircraft;
import com.example.aircraft.base.AbstractFlyingObject;
import com.example.aircraft.base.MusicThread;
import com.example.aircraft.bullet.AbstractBullet;
import com.example.aircraft.database.MySqlManager;
import com.example.aircraft.database.MySqliteHelper;
import com.example.aircraft.database.SQLiteInterface;
import com.example.aircraft.database.User_Data;
import com.example.aircraft.panel.ChoosePattern;
import com.example.aircraft.prop.AbstractProp;
import com.example.aircraft.prop.PropFactory;
import com.example.aircraft.prop.PropStategy;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public abstract class GameBase extends SurfaceView implements SurfaceHolder.Callback,Runnable {
    private static final String TAG = "success";
    protected MySqliteHelper helper;
    protected Paint mPaint;
    protected SurfaceHolder holder;
    protected Canvas canvas;

    protected static User_Data user_data;
    protected int bkGroundId;
    protected boolean isValid;
    protected int bkGroundTop;
    protected HeroAircraft hero;
    protected final List<Enemy> enemyAircrafts;

    public static final EnemyObject enemyManager = new EnemyObject();
    protected final List<AbstractBullet> heroBullets;
    //敌机子弹
    protected final List<AbstractBullet> enemyBullets;
    protected final List<AbstractProp> Props;
    protected int level=1;
    protected EnemyFactory enemyFactory;

    protected PropStategy propManeger;

    protected int enemyMaxNumber = 5;
    protected static int score = 0;
    /**
     * 时间间隔(ms)，控制刷新频率
     */
    protected int timeInterval = 300;
    protected final int timeIntervaL_Hero = 30;
    /**
     * 周期（ms)
     * 指示子弹的发射、敌机的产生频率
     */
    protected int cycleDuration = 6000;
    protected int cycleTime = 0;
    protected final int cycleDuration_Hero = 600;
    protected int cycleTime_Hero = 0;

    //试图用这个降低射击频率
    private int site=0;
    //

    public GameBase(Context context) {
        super(context);
        HeroAircraft.Init();
        hero = HeroAircraft.newInstance();
        new HeroController(this,hero);

        helper = MySqlManager.getInstance(MyApplication.getContext());




        user_data = DualSignPanel.getUser_data();

        holder = getHolder();
        holder.addCallback(this);
        mPaint = new Paint();
        bkGroundTop = 0;
        enemyAircrafts = new LinkedList<>();
        heroBullets = new LinkedList<>();
        enemyBullets = new LinkedList<>();
        Props = new LinkedList<>();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder){
            isValid = true;
            new Thread(this).start();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){

    }
    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
        this.isValid = false;
    }
    @Override
    public void run(){
        while(this.isValid) {
            draw_bg();
            if (timeCountAndNewCycleJudge()) {
                // 新敌机产生
                if (enemyAircrafts.size() < enemyMaxNumber) {
                    Enemy enemy = enemyFactory.setEnemy(this.score);
                    enemyAircrafts.add(enemy);
                    enemy.registerObject(enemyManager);
                }
                // 飞机射出子弹,试图用状态机
                if(site==0) {
                    enemyshootAction();
                    site++;
                }else{
                    site=0;
                }

            }
            if (timeCountAndNewCycleJudge_Hero()) {
                //英雄机射出子弹
                heroshootAction();
            }
            // 子弹移动
            bulletsMoveAction();
            // 飞机移动
            aircraftsMoveAction();
            //补给移动
            propsMoveAction();
            // 撞击检测
            crashCheckAction();
            // 后处理
            postProcessAction();
            if(hero.notValid()){
                user_data.addToCrdits(this.score);
                updateUserdata();
                insertToRankDB();
                Intent intent  = new Intent(this.getContext(), ChoosePattern.class);
                this.getContext().startActivity(intent);
                break;
            }

            try {
                Thread.sleep(timeIntervaL_Hero);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    protected void enemyshootAction() {
        // TODO 敌机射击
        for (AbstractAircraft enemyAircraft : enemyAircrafts){
            enemyBullets.addAll(enemyAircraft.shoot());
        }


    }
    protected void heroshootAction() {
        // 英雄射击
        heroBullets.addAll(hero.shoot());
    }

    protected void bulletsMoveAction() {
        for (AbstractBullet bullet : heroBullets) {
            bullet.forward();
        }
        for (AbstractBullet bullet : enemyBullets) {
            bullet.forward();
        }
    }

    protected void aircraftsMoveAction() {
        for (AbstractAircraft enemyAircraft : enemyAircrafts) {
            enemyAircraft.forward();
        }
    }
    protected void propsMoveAction(){
        for(AbstractProp prop:Props){
            prop.forward();
        }
    }


    /**
     * 碰撞检测：
     * 1. 敌机攻击英雄
     * 2. 英雄攻击/撞击敌机
     * 3. 英雄获得补给
     */
    protected void crashCheckAction() {
        // TODO 敌机子弹攻击英雄
        for (AbstractBullet bullet : enemyBullets) {
            bullet.registerObject(enemyManager);
            for (AbstractAircraft enemyAircraft : enemyAircrafts) {
                if (enemyAircraft.notValid()) {
                    continue;
                }
                if (hero.crash(bullet)) {

                    hero.decreaseHp(bullet.getPower());
                    bullet.vanish();
                }
            }
        }
        // 英雄子弹攻击敌机
        for (AbstractBullet bullet : heroBullets) {
            if (bullet.notValid()) {
                continue;
            }
            for (Enemy enemyAircraft : enemyAircrafts) {
                if (enemyAircraft.notValid()) {
                    // 已被其他子弹击毁的敌机，不再检测
                    // 避免多个子弹重复击毁同一敌机的判定
                    continue;
                }
                if (enemyAircraft.crash(bullet)) {
                    // 敌机撞击到英雄机子弹
                    // 敌机损失一定生命值
                    enemyAircraft.decreaseHp(bullet.getPower());
                    MusicThread musicThread = new MusicThread(R.raw.bullet_hit);
                    musicThread.start();
                    bullet.vanish();
                    if (enemyAircraft.notValid()) {
//                            score+=enemyAircraft.getValue();

                        Props.addAll(enemyAircraft.dropProp());
                    }
                }
                // 英雄机 与 敌机 相撞，均损毁
                if (enemyAircraft.crash(hero) || hero.crash(enemyAircraft)) {
                    enemyAircraft.vanish();
                    hero.decreaseHp(hero.getHp());
                }

            }

        }

        //
        // Todo: 我方获得道具，道具生效
        for(AbstractProp prop:Props){
            if(prop.notValid()){
                continue;
            }
            if(hero.crash(prop)||prop.crash(hero)){
                prop.registerTargets(enemyAircrafts);
                propManeger = new PropStategy(prop);
                propManeger.propExecute();
            }

        }

    }

    /**
     * 后处理：
     * 1. 删除无效的子弹
     * 2. 删除无效的敌机
     * 3. 检查英雄机生存
     * <p>
     * 无效的原因可能是撞击或者飞出边界
     */
    protected void postProcessAction() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        enemyBullets.removeIf(AbstractFlyingObject::notValid);

        heroBullets.removeIf(AbstractFlyingObject::notValid);

        for(Enemy enemy:enemyAircrafts){
            if(enemy.getHp()<=0){
                score+=enemy.getValue();}
        }
        enemyAircrafts.removeIf(AbstractFlyingObject::notValid);
        Props.removeIf(AbstractFlyingObject::notValid);
        }
    }





    /**
     * 绘制函数
     */
    protected void draw_bg() {
        try {
            canvas = holder.lockCanvas();
            //缩放背景图片
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), bkGroundId);
            float scale_w = (float)canvas.getWidth()/bmp.getWidth();
            float scale_h = (float)canvas.getHeight()/bmp.getHeight();
            Matrix matrix = new Matrix();
            matrix.postScale(scale_w,scale_h);
            bmp = Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true);
            canvas.drawBitmap(bmp, 0, bkGroundTop-canvas.getHeight(), mPaint);
            canvas.drawBitmap(bmp,0,bkGroundTop,mPaint);
            //实现滚动效果↑
            bkGroundTop++;
            if(bkGroundTop==canvas.getHeight()){
                bkGroundTop = 0;
            }

            canvas.drawBitmap(ImageManager.HERO_IMAGE,hero.getLocationX()-ImageManager.HERO_IMAGE.getWidth()/2,
                    hero.getLocationY() - ImageManager.HERO_IMAGE.getHeight() / 2,mPaint);

            for (AbstractFlyingObject object : heroBullets) {
                Bitmap image = object.getImage();
                assert image != null : heroBullets.getClass().getName() + " has no image! ";
                canvas.drawBitmap(image, object.getLocationX() - image.getWidth() / 2,
                        object.getLocationY() - image.getHeight() / 2, mPaint);}

            for (AbstractFlyingObject object : enemyBullets) {

                Bitmap image = object.getImage();
                assert image != null : enemyBullets.getClass().getName() + " has no image! ";
                canvas.drawBitmap(image, object.getLocationX() - image.getWidth() / 2,
                        object.getLocationY() - image.getHeight() / 2, mPaint);}

            for (AbstractFlyingObject object : Props) {

                Bitmap image = object.getImage();
                assert image != null : Props.getClass().getName() + " has no image! ";
                canvas.drawBitmap(image, object.getLocationX() - image.getWidth() / 2,
                        object.getLocationY() - image.getHeight() / 2, mPaint);}

            for (AbstractFlyingObject object : enemyAircrafts) {

                Bitmap image = object.getImage();
                assert image != null : enemyAircrafts.getClass().getName() + " has no image! ";
                canvas.drawBitmap(image, object.getLocationX() - image.getWidth() / 2,
                        object.getLocationY() - image.getHeight() / 2, mPaint);}



                mPaint.setStyle(Paint.Style.FILL);
                mPaint.setTextSize(50);
                mPaint.setStrokeWidth(12);
                mPaint.setColor(Color.RED);///////////
                canvas.drawText("分数:"+this.score,0 , 100, mPaint);
                canvas.drawText("HP:"+hero.getHp(),0 , 160, mPaint);
                canvas.drawText("护盾值:"+hero.getSheld(),0 , 220, mPaint);

                /////////////////保证数据是新的
                user_data = DualSignPanel.getUser_data();
                ///////////////道具数量
                canvas.drawText("回血道具:"+user_data.getSHEILD(),0,1400,mPaint);
                canvas.drawText("弹药道具:"+user_data.getCLUSTER(),0,1600,mPaint);
                canvas.drawText("炸弹道具:"+user_data.getHEMOPHAGIA(),0,1800,mPaint);
                ///////////////准备用道具图片作为触发
                canvas.drawBitmap(ImageManager.PROP_BLOOD_IMAGE,0,1440,mPaint);
                canvas.drawBitmap(ImageManager.PROP_BULLET_IMAGE,0,1630,mPaint);
                canvas.drawBitmap(ImageManager.PROP_BOMB_IMAGE,0,1820,mPaint);
                ///////////////这个应该是只画一次就行吧，但是目前不知道怎么整，就一直反复画吧
        }
        catch(Exception e){
            e.printStackTrace();
        }
        finally {
            holder.unlockCanvasAndPost(canvas);
        }
    }

    protected void paintImageWithPositionRevised(List<? extends AbstractFlyingObject> objects) {
        if (objects.size() == 0) {
            return;
        }

        try{

            for (AbstractFlyingObject object : objects) {
            canvas = holder.lockCanvas();

            Bitmap image = object.getImage();
            assert image != null : objects.getClass().getName() + " has no image! ";
            canvas.drawBitmap(image, object.getLocationX() - image.getWidth() / 2,
                    object.getLocationY() - image.getHeight() / 2, mPaint);}
        }catch(Exception e){
            e.printStackTrace();
        }
        finally {
            holder.unlockCanvasAndPost(canvas);
        }

    }
    protected boolean timeCountAndNewCycleJudge() {
        cycleTime += timeInterval;
        if (cycleTime >= cycleDuration && cycleTime - timeInterval < cycleTime) {
            // 跨越到新的周期
            cycleTime %= cycleDuration;
            return true;
        } else {
            return false;
        }
    }


    protected boolean timeCountAndNewCycleJudge_Hero() {
        cycleTime_Hero += timeIntervaL_Hero;
        if (cycleTime_Hero >= cycleDuration_Hero && cycleTime_Hero - timeIntervaL_Hero < cycleTime_Hero) {
            // 跨越到新的周期
            cycleTime_Hero %= cycleDuration_Hero;
            return true;
        } else {
            return false;
        }
    }
    protected void paint(){
        draw_bg();
        paintImageWithPositionRevised(Props);
        paintImageWithPositionRevised(enemyBullets);
        paintImageWithPositionRevised(heroBullets);
        paintImageWithPositionRevised(enemyAircrafts);

    }
    protected  void insertToRankDB(){
        int i=1;
        SQLiteDatabase db = helper.getReadableDatabase();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = simpleDateFormat.format(date);
        String selectSql = "select * from "+ SQLiteInterface.TABLE1_NAME;//写入排行榜用数据库表
        Cursor cursor = MySqlManager.selectSQL(db,selectSql,null);//查询结果用cursor类型数据存储
        while (cursor.moveToNext()){
        int columnIndx = cursor.getColumnIndex(SQLiteInterface.ID);
        i = cursor.getInt(columnIndx)+1;
        //永远比最后一个的id大1
        }
        //获取到数据插入数据库
        ContentValues values = new ContentValues();
        values.put("id",i);
        values.put(SQLiteInterface.USER,this.user_data.getUSER_NAME());
        values.put(SQLiteInterface.SCORE,this.score);
        values.put(SQLiteInterface.TIME,time);
        values.put("Level",this.level);
        db.insert(SQLiteInterface.TABLE1_NAME, null, values);
        db.close();
        Log.d("WRITE","插入数据库");
    }

    protected void updateUserdata(){
        SQLiteDatabase db = helper.getWritableDatabase();
        String selectSql = "select * from "+ SQLiteInterface.TABLE2_NAME;
        ContentValues values = new ContentValues();
        values.put(SQLiteInterface.CREDITS,user_data.getCREDITS());
        int rowcount = db.update(SQLiteInterface.TABLE2_NAME,
                values,
                SQLiteInterface.USER_NAME+"=?",
                new String[] {user_data.getUSER_NAME() });
        db.close();
    }
}
